package com.union.pay.ccb.service.impl;

import CCBSign.RSASig;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.union.pay.ccb.bean.req.CcbPayReq;
import com.union.pay.ccb.bean.req.CcbTakeMacReq;
import com.union.pay.ccb.bean.vo.CallbackVerifyVo;
import com.union.pay.ccb.bean.vo.CcbVo;
import com.union.pay.ccb.bean.vo.CcbWxJsapiResult;
import com.union.pay.ccb.config.CcbPayConfig;
import com.union.pay.ccb.config.CcbPayConfigHolder;
import com.union.pay.ccb.exception.UnionPayException;
import com.union.pay.ccb.service.CcbPayService;
import com.union.pay.ccb.utils.CcbConvertUtils;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;

@Slf4j
public class CcbPayServiceImpl implements CcbPayService {

    protected Map<String, CcbPayConfig> configMap;

    @Override
    public void setPayConfig(CcbPayConfig config) {
        final String defaultMchId = config.getMerchantId();
        this.setMultiConfig(ImmutableMap.of(defaultMchId, config), defaultMchId);
    }

    @Override
    public void setMultiConfig(Map<String, CcbPayConfig> wxPayConfigs, String defaultMchId) {
        this.configMap = Maps.newHashMap(wxPayConfigs);
        CcbPayConfigHolder.set(defaultMchId);
    }

    @Override
    public CcbPayConfig getPayConfig() {
        if (this.configMap.size() == 1) {
            // 只有一个商户号，直接返回其配置即可
            return this.configMap.values().iterator().next();
        }
        return this.configMap.get(CcbPayConfigHolder.get());
    }

    public CcbWxJsapiResult purchase(CcbPayReq req) {
        CcbTakeMacReq macReq = this.ccbPay(req);
        String value = CcbConvertUtils.getCcbParam(macReq, false);
        macReq.setPUB(this.getPayConfig().getPub());
        String md5 = CcbConvertUtils.getCcbParam(macReq, true);
        String ccbParam = value + md5;

        String url = String.format("%s&%s", this.getPayConfig().getUrl(), ccbParam);

        System.out.println(url);


        String result = HttpUtil.post(url, "");
        CcbVo ccbVo = null;
        try {
            ccbVo = JSONObject.parseObject(result, CcbVo.class);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("第一次请求建行 抱歉调用建行支付接口失败 {} {}", e.getMessage(), result);
            throw new UnionPayException("抱歉调用建行支付接口失败");
        }
        if (null == ccbVo || !Boolean.TRUE.toString().equalsIgnoreCase(ccbVo.getSuccess())) {
            throw new UnionPayException("抱歉调用建行支付接口失败");
        }
        String wxResult = HttpUtil.get(ccbVo.getPayUrl());

        try {
            return JSONObject.parseObject(wxResult, CcbWxJsapiResult.class);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("第二次请求建行 抱歉调用建行支付接口失败 {} {}", e.getMessage(), wxResult);
            throw new UnionPayException("抱歉调用建行支付接口失败");
        }
    }

    @Override
    public void verify(Map<String, String> map) {
        String sb = "POSID=" + map.get("POSID") + "&BRANCHID=" + map.get("BRANCHID") +
                "&ORDERID=" + map.get("ORDERID") + "&PAYMENT=" + map.get("PAYMENT") +
                "&CURCODE=" + map.get("CURCODE") + "&REMARK1=" + map.get("REMARK1") +
                "&REMARK2=" + map.get("REMARK2") + "&ACC_TYPE=" + map.get("ACC_TYPE") +
                "&SUCCESS=" + map.get("SUCCESS") + "&ACCDATE=" + map.get("ACCDATE");
        RSASig rsaSig = new RSASig();
        // 公钥
        rsaSig.setPublicKey(this.getPayConfig().getPublicKey());

        boolean flag = rsaSig.verifySigature(map.get("SIGN"), sb);
        log.info("callBackCCB Check :[{}]", flag);
        //表示支付成功
        if ("Y".equals(map.get("SUCCESS")) && flag) {
            CallbackVerifyVo callbackResult = new CallbackVerifyVo();
            callbackResult.setReturnCode("Y");
            callbackResult.setReturnMsg("Ok");
            callbackResult.setOrderNo(map.get("ORDERID"));
        } else {
            throw new UnionPayException("建行回调异常");
        }
    }

    @Override
    public void test() {
        System.out.println(this.getPayConfig());
    }


    private CcbTakeMacReq ccbPay(CcbPayReq req) {
        CcbTakeMacReq macReq = new CcbTakeMacReq();
        macReq.setSUB_APPID(this.getPayConfig().getAppId());
        macReq.setMERCHANTID(this.getPayConfig().getMerchantId());
        macReq.setPOSID(this.getPayConfig().getPosId());
        macReq.setBRANCHID(this.getPayConfig().getBranchId());
        macReq.setCURCODE(this.getPayConfig().getCurCode());
        macReq.setTXCODE(this.getPayConfig().getTxCode());
        macReq.setGATEWAY(this.getPayConfig().getGateway());
        macReq.setTYPE(this.getPayConfig().getType());

        macReq.setORDERID(req.getOrderId());
        macReq.setPAYMENT(req.getPayment());
        macReq.setSUB_OPENID(req.getOpenId());
        macReq.setCLIENTIP(req.getClientIp());
        macReq.setREMARK1(req.getRemark());
        macReq.setREMARK2(req.getRemark2());
        macReq.setTRADE_TYPE(req.getTradeType());
        return macReq;
    }

}
